package com.haojiang.mh.widget.chart;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.*;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
import com.haojiang.mh.R;
import com.haojiang.mh.service.entity.MinMaxBean;
import com.haojiang.mh.service.entity.MinMaxChartBean;
import com.haojiang.mh.service.entity.TwoValueChartBean;
import com.haojiang.mh.utils.SizeUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * 双X轴+线条格背景+柱状图（中心点圆角单柱、中心点左右双矩形柱）
 * 当前用在《周报--心率、呼吸、体动、录音 打鼾》
 */
public class WeekSignChartView extends View {

    public static final int ROUND_RECT = 0;
    public static final int TWO_COLUMN = 1;
    private TextPaint textPaint;//文字画笔
    private Paint coordinatePaint, columnPaint;//线、圆柱 画笔
    //Y轴开始点值、Y轴间隔大小、Y轴坐标个数（去除起点个数）
    private int yStartCoordinate, yInterval, yCoordinateNum, yMaxCoordinate;
    private String[] xAxisBottom, xAxisTop;//X轴上下坐标对应文本
    //工作日文本、周末文本、左侧柱、右侧柱、背景线、坐标刻度 颜色
    private int workDayColor, weekendColor, leftColumnColor, rightColumnColor, bgLineColor;
    private RectF rectF = new RectF();//矩形
    private int xAxisTextSize, yAxisTextSize;//X轴文本、Y轴文本字体大小
    //X轴文本高、Y轴文本高、Y轴宽度、X轴高度、圆角柱子宽度、X轴间隔块宽度、Y轴起始点、绘制高度
    private int xAxisTextHeight, yAxisTextHeight, yAxisWidth, xAxisHeight, columnWidth, xItemWidth, bottomY, drawHeight;
    private float xItemGap, yItemHeight;
    private int width, height, defaultWidth, defaultHeight;//当前View宽高、默认宽高度
    private LinearGradient shader;//渐变
    private int columnGraBottomColor, columnGraTopColor;//最底、最顶 渐变色值
    private List<MinMaxChartBean> roundRectList;//圆柱数据集
    private List<TwoValueChartBean> twoColumnList;//双柱数据集
    private int chartType;//图表类型 ROUND、DOUBLE
    private int doubleColumnGap;//DOUBLE类型下两柱子之间间隔
    private int mDefaultYMaxValue;//y轴默认最大值

    public WeekSignChartView(Context context) {
        this(context, null);
    }

    public WeekSignChartView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public WeekSignChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        @SuppressLint("CustomViewStyleable")
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ChartModuleAttribute, defStyleAttr, 0);
        yStartCoordinate = a.getInt(R.styleable.ChartModuleAttribute_cm_y_start, 0);
        yInterval = a.getInt(R.styleable.ChartModuleAttribute_cm_y_interval, 5);
        yCoordinateNum = a.getInt(R.styleable.ChartModuleAttribute_cm_y_number, 8);
        chartType = a.getInt(R.styleable.ChartModuleAttribute_cm_chart_type, ROUND_RECT);
        leftColumnColor = a.getColor(R.styleable.ChartModuleAttribute_cm_left_color, getResources().getColor(R.color.purple_3));
        rightColumnColor = a.getColor(R.styleable.ChartModuleAttribute_cm_right_color, getResources().getColor(R.color.purple_4));
        mDefaultYMaxValue = yStartCoordinate + yInterval * yCoordinateNum;
        a.recycle();
        initView(context);
    }

    private void initView(Context context) {
        xAxisTextHeight = SizeUtil.dp2px(context, 30);
        yAxisTextHeight = SizeUtil.dp2px(context, 20);
        xAxisHeight = SizeUtil.dp2px(context, 3);
        yAxisWidth = SizeUtil.dp2px(context, 30);
        xItemWidth = SizeUtil.dp2px(context, 20);
        columnWidth = SizeUtil.dp2px(context, 5);
        doubleColumnGap = SizeUtil.dp2px(context, 1);
        drawHeight = SizeUtil.dp2px(context, 130);

        defaultWidth = SizeUtil.dp2px(context, 340);
        defaultHeight = xAxisTextHeight + drawHeight + xAxisHeight + xAxisTextHeight;

        xAxisBottom = new String[]{"20", "21", "22", "23", "24", "25", "26"};
        xAxisTop = getResources().getStringArray(R.array.chinaWeekDayArray);

        workDayColor = getResources().getColor(R.color.white_half);
        weekendColor = getResources().getColor(R.color.purple_3);
        bgLineColor = getResources().getColor(R.color.white) & 0x19FFFFFF;
        columnGraBottomColor = getResources().getColor(R.color.purple_5);
        columnGraTopColor = getResources().getColor(R.color.purple_3);

        xAxisTextSize = SizeUtil.sp2px(context, 12);
        yAxisTextSize = SizeUtil.sp2px(context, 10);

        textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setTextAlign(Paint.Align.CENTER);

        coordinatePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        coordinatePaint.setStyle(Paint.Style.FILL);
        coordinatePaint.setColor(workDayColor);
        coordinatePaint.setStrokeWidth(2);

        columnPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        columnPaint.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (chartType == ROUND_RECT) {
            if (roundRectList == null || roundRectList.isEmpty()) return;
        } else {
            if (twoColumnList == null || twoColumnList.isEmpty()) return;
        }

        yMaxCoordinate = yStartCoordinate + yInterval * yCoordinateNum;
        xItemGap = (float) (width - yAxisWidth - xItemWidth * 7) / 6;//除去柱的宽度两个item之间的空白宽度
        yItemHeight = (float) drawHeight / yCoordinateNum;
        bottomY = height - xAxisTextHeight - xAxisHeight;

        drawXAxis(canvas);

        drawYAxis(canvas);

        /* 绘制线或柱状 */
        if (chartType == ROUND_RECT) {
            drawRoundRectView(canvas);
        } else {
            drawTwoColumnView(canvas);
        }
    }

    /**
     * 绘制X轴
     */
    private void drawXAxis(Canvas canvas) {
        textPaint.setTextSize(xAxisTextSize);
        for (int i = 0; i < xAxisTop.length; i++) {
            float xItemMidPosition = xItemWidth * 0.5f + (xItemWidth + xItemGap) * i;
            textPaint.setColor((i == 5 || i == 6) ? weekendColor : workDayColor);
            //上轴
            canvas.drawText(
                    xAxisTop[i],
                    xItemMidPosition,
                    SizeUtil.getBaseLine(textPaint, xAxisTextHeight, xAxisTextHeight),
                    textPaint
            );
            //下轴
            canvas.drawLine(
                    xItemMidPosition,
                    bottomY,
                    xItemMidPosition,
                    bottomY + xAxisHeight,
                    coordinatePaint
            );
            canvas.drawText(
                    xAxisBottom[i],
                    xItemMidPosition,
                    SizeUtil.getBaseLine(textPaint, height, xAxisTextHeight),
                    textPaint
            );
        }
    }

    /**
     * 绘制Y轴和背景线
     */
    private void drawYAxis(Canvas canvas) {
        textPaint.setColor(workDayColor);
        textPaint.setTextSize(yAxisTextSize);
        coordinatePaint.setColor(bgLineColor);
        for (int i = 0; i <= yCoordinateNum; i++) {//从上至下
            canvas.drawLine(//背景线
                    0,
                    bottomY - i * yItemHeight,
                    width - yAxisWidth,
                    bottomY - i * yItemHeight,
                    coordinatePaint
            );
            if (i == 0) continue;
            float yTextBaseLine = bottomY - i * yItemHeight + yAxisTextHeight * 0.5f;
            canvas.drawText(//Y坐标系
                    String.valueOf(yStartCoordinate + i * yInterval),
                    width - yAxisWidth * 0.5f,
                    SizeUtil.getBaseLine(textPaint, yTextBaseLine, yAxisTextHeight),
                    textPaint
            );
        }
    }

    /**
     * 绘制圆角柱（带渐变）
     */
    private void drawRoundRectView(Canvas canvas) {
        for (int i = 0; i < roundRectList.size(); i++) {
            MinMaxChartBean bean = roundRectList.get(i);
            if (bean == null || bean.getLine() == null || bean.getLine().isNull()) continue;
            MinMaxBean mmb = bean.getLine();
            if (mmb.getMax() == mmb.getMin()) continue;
            if (mmb.getMax() <= yStartCoordinate || mmb.getMin() >= yMaxCoordinate) continue;
            if (mmb.getMin() < yStartCoordinate) mmb.setMin(yStartCoordinate);
            if (mmb.getMax() > yMaxCoordinate) mmb.setMax(yMaxCoordinate);
            float xItemMidPosition = xItemWidth * 0.5f + (xItemWidth + xItemGap) * i;
            float top = bottomY - (mmb.getMax() - yStartCoordinate) * drawHeight * 1.0f / (yMaxCoordinate - yStartCoordinate);
            float bottom = bottomY - (mmb.getMin() - yStartCoordinate) * drawHeight * 1.0f / (yMaxCoordinate - yStartCoordinate);
            rectF.set(xItemMidPosition - columnWidth * 0.5f, top, xItemMidPosition + columnWidth * 0.5f, bottom);
            shader = new LinearGradient(0, bottom, 0, top, columnGraBottomColor, columnGraTopColor, Shader.TileMode.CLAMP);
            columnPaint.setShader(shader);
            canvas.drawRoundRect(rectF, columnWidth * 0.5f, columnWidth * 0.5f, columnPaint);
        }
    }

    /**
     * 绘制双矩形柱
     */
    private void drawTwoColumnView(Canvas canvas) {
        for (int i = 0; i < twoColumnList.size(); i++) {
            TwoValueChartBean bean = twoColumnList.get(i);
            if (bean == null || bean.isNull()) continue;
            if (bean.getLeftValue() < yStartCoordinate) continue;
            if (bean.getRightValue() < yStartCoordinate) continue;
            if (bean.getLeftValue() > yMaxCoordinate) bean.setLeftValue(yMaxCoordinate);
            if (bean.getRightValue() > yMaxCoordinate) bean.setRightValue(yMaxCoordinate);
            float xItemMidPosition = xItemWidth * 0.5f + (xItemWidth + xItemGap) * i;
            //左边柱子
            rectF.set(
                    xItemMidPosition - xItemWidth * 0.5f,
                    bottomY - (bean.getLeftValue() - yStartCoordinate) * drawHeight * 1.0f / (yMaxCoordinate - yStartCoordinate),
                    xItemMidPosition - doubleColumnGap * 0.5f,
                    bottomY
            );
            columnPaint.setColor(leftColumnColor);
            canvas.drawRect(rectF, columnPaint);
            //右边柱子
            rectF.set(
                    xItemMidPosition + doubleColumnGap * 0.5f,
                    bottomY - (bean.getRightValue() - yStartCoordinate) * drawHeight * 1.0f / (yMaxCoordinate - yStartCoordinate),
                    xItemMidPosition + xItemWidth * 0.5f,
                    bottomY
            );
            columnPaint.setColor(rightColumnColor);
            canvas.drawRect(rectF, columnPaint);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(
                getMeasuredLength(widthMeasureSpec, true),
                getMeasuredLength(heightMeasureSpec, false)
        );
    }

    private int getMeasuredLength(int length, boolean isWidth) {
        int specMode = MeasureSpec.getMode(length);
        int specSize = MeasureSpec.getSize(length);
        int size;
        int padding = isWidth ? getPaddingLeft() + getPaddingRight() : getPaddingTop() + getPaddingBottom();
        if (specMode == MeasureSpec.EXACTLY) {
            size = specSize;
        } else if (specMode == MeasureSpec.UNSPECIFIED) {
            size = isWidth ? defaultWidth : defaultHeight;
        } else {
            size = isWidth ? padding + defaultWidth : padding + defaultHeight;
            if (specMode == MeasureSpec.AT_MOST) {
                size = Math.min(size, specSize);
            }
        }
        return size;
    }

    /**
     * 设定圆角柱数据集
     */
    public void setRoundRectData(List<MinMaxChartBean> data) {
        this.chartType = ROUND_RECT;
        if (roundRectList == null) roundRectList = new ArrayList<>();
        roundRectList.clear();
        if (data != null && !data.isEmpty()) {
            roundRectList.addAll(data);
            int max = 0;
            for (int i = 0; i < roundRectList.size(); i++) {
                MinMaxChartBean bean = roundRectList.get(i);
                xAxisBottom[i] = bean.getDay();
                max = Math.max(bean.getLine().getMax(), max);
            }
            int finalMax = Math.max(max, mDefaultYMaxValue);
            double ceil = Math.ceil(finalMax * 1.0f / mDefaultYMaxValue);
            yInterval = (int) (mDefaultYMaxValue * ceil / yCoordinateNum);
        }
        invalidate();
    }

    /**
     * 设定双矩形柱数据集
     */
    public void setTwoColumnData(List<TwoValueChartBean> data) {
        this.chartType = TWO_COLUMN;
        if (twoColumnList == null) twoColumnList = new ArrayList<>();
        twoColumnList.clear();
        if (data != null && !data.isEmpty()) {
            twoColumnList.addAll(data);
            int max = 0;
            for (int i = 0; i < twoColumnList.size(); i++) {
                TwoValueChartBean bean = twoColumnList.get(i);
                xAxisBottom[i] = bean.getDay();
                int maxNum = Math.max(bean.getLeftValue(), bean.getRightValue());
                max = Math.max(maxNum, max);
            }
            int finalMax = Math.max(max, mDefaultYMaxValue);
            double ceil = Math.ceil(finalMax * 1.0f / mDefaultYMaxValue);
            yInterval = (int) (mDefaultYMaxValue * ceil / yCoordinateNum);
        }
        invalidate();
    }
}

